package com.ebook.server.service;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.ModelAndView;

import com.ebook.core.domain.User;
import com.ebook.util.DataUtil;
import com.ebook.util.ErrorCode;
import com.ebook.util.MD5;
import com.ebook.util.SendAttachment;
import com.ebook.util.Status;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

/**
 * 用户管理的Service层
 * @author   潘吉友
 * @Date	 2013-2-25
 */
@Service
@Transactional
public class UserService {

	private static DateFormat SDF = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");

	@Resource
	private JdbcTemplate jdbcTemplate;
	
	/**
	 * 重置密码功能
	 * @param email
	 * @param password
	 * @param password1
	 * @return 重置成功转重置成功页面；失败转到重置密码页面
	*/
	public ModelAndView resetPsw(String email, String password, String password1) {
		ModelAndView modelView = new ModelAndView();
		Map<String, Object> modelMap = new HashMap<String, Object>();
		String status = Status.SUCCESS;
		if (!DataUtil.checkString(password, password1)) {
			status = Status.REJECTED + ":" + ErrorCode.MODIFY_PASSWORD_FAIL;
			modelView.setViewName("/user/resetpass");
		} else {
			String passwordMd5 = MD5.getEncryptedPwd(password);
			if (!modifyPswByEmail(passwordMd5, email)) {
				status = Status.REJECTED + ":" + ErrorCode.MODIFY_PASSWORD_FAIL;
				modelView.setViewName("/user/resetpass");
			}else{
				modelView.setViewName("/user/resetpsw_s");
			}
		}
		modelMap.put("status", status);
		modelMap.put("email", email);
		modelView.addAllObjects(modelMap);
		return modelView;
	}
	
	
	/**
	 * 核对email和动态码，成功跳转到重置密码页面，失败跳转到错误页面
	 * @param email
	 * @param checkcode
	 * @return 视图
	*/
	public ModelAndView editPsw(String email, String checkcode) {
		ModelAndView modelView = new ModelAndView();
		Map<String, Object> modelMap = new HashMap<String, Object>();
		if(checkCode(email,checkcode)){
			modelMap.put("email", email);
			modelMap.put("checkcode", checkcode);
			modelView.setViewName("/user/resetpass");
		}else{
			modelMap.put("status", "您的邮箱或动态码错误！");
			modelView.setViewName("/user/linkerror");
		}
		modelView.addAllObjects(modelMap);
		return modelView;
	}
	
	/**
	 * 给email地址发邮件
	 * @param email
	 * @param request
	 * @return 成功失败信息
	*/
	@SuppressWarnings("unused")
	public ModelAndView sendPswByEmail(String email) {
		ModelAndView modelView = new ModelAndView();
		Map<String, Object> modelMap = new HashMap<String, Object>();
		String status = Status.SUCCESS;
		if(email !=null || email != ""){
				String checkcode = DataUtil.randomCheckCode();
				if(!SendAttachment.sendPswByMail(email,checkcode)){
					status = Status.REJECTED + ":" + ErrorCode.EMAIL_SEND_FAIL;
				}
				updataCheckCode(email,checkcode);
       }else{
    	   status = Status.REJECTED + ":" + ErrorCode.EMAIL_SEND_FAIL;
       }
		modelMap.put("status", status);
		modelView.addAllObjects(modelMap);
		return modelView;
	}
	
	/**
	 * 返回没有用户权限的试图
	 * @param modelView
	 * @param modelMap
	 * @return ModelAndView
	 */
	public ModelAndView notLoginView(ModelAndView modelView, Map<String, Object> modelMap) {
		modelMap.put("error", true);
		modelMap.put("errormsg", "用户不存在或您没有权限查看！");
		String status = Status.REJECTED + ":" + ErrorCode.NOT_LOGIN;
		modelMap.put("status", status);
		modelView.addAllObjects(modelMap);
		return modelView;
	}
	
	public ModelAndView regist(String email,String password,String name,String type) {
		ModelAndView modelView = new ModelAndView();
    	Map<String,Object> modelMap=new HashMap<String,Object>();  
    	String status = Status.SUCCESS;
		if (name == null || name.trim().isEmpty() ) {
			status = Status.REJECTED + ":" + ErrorCode.INVALID_USER_NAME;
		}
		else if (email == null || email.trim().isEmpty()) {
			status = Status.REJECTED + ":" + ErrorCode.INVALID_EMAIL;
		}
		else if (password == null || password.trim().isEmpty()) {
			status = Status.REJECTED + ":" + ErrorCode.INVALID_PASSWORD;
		}
		else {
			if (isUserExist(email)) {
				status = Status.REJECTED + ":" + ErrorCode.DUPLICATE_EMAIL;
			}
			else {
				User user = registerUser(name, email, password, type);
				if (user == null) {
					status = Status.REJECTED + ":" + ErrorCode.UNKNOWN;
				}else{
					 modelMap.put("user", user);
				}
			}
		}
		modelMap.put("status", status);
		modelView.addAllObjects(modelMap);
        return modelView;
	}
	
	public ModelAndView login(String email, String password,
			HttpServletRequest request) {
		ModelAndView modelView = new ModelAndView();
		Map<String,Object> modelMap=new HashMap<String,Object>();
		String status = Status.SUCCESS;
		if(email == null){
			status = Status.REJECTED + ":" + ErrorCode.INVALID_EMAIL;
		}
     
		if (!isUserExist(email)) {
			status = Status.REJECTED + ":" + ErrorCode.INVALID_EMAIL;
		}
		else {
			User user = getUserInfo(email, password);
			if (user == null) {
				status = Status.REJECTED + ":" + ErrorCode.INVALID_PASSWORD;
			}else{
				request.getSession().setAttribute("loginuser", user);
				modelMap.put("user", user);
			}
		}
        modelMap.put("status", status);
        modelView.addAllObjects(modelMap);
        return modelView;
	}
	
	public ModelAndView modifyPassword(HttpServletRequest request) {
		ModelAndView modelView = new ModelAndView();
		Map<String,Object> modelMap=new HashMap<String,Object>();
        long userId =Long.valueOf(request.getParameter("userId")) ;
		String oldPassword = request.getParameter("oldPassword");
		String newPassword = request.getParameter("newPassword");
		String newPassword1 = request.getParameter("newPassword1");
		String status = Status.SUCCESS;
		String oldPasswordv = null;
		String newPasswordv = null;
		if(oldPassword == null){
			oldPasswordv = "旧密码不能为空！";
			modelMap.put("oldPasswordv", oldPasswordv);
		}
		else if(!newPassword.equals(newPassword1)){
			newPasswordv = "新密码两次输入不符！";
			modelMap.put("newPasswordv", newPasswordv);
		}
		else{
			if (!modifyPassword(userId, oldPassword, newPassword)) {
				status = Status.REJECTED + ":" + ErrorCode.MODIFY_PASSWORD_FAIL;
				oldPasswordv = "旧密码输入错误！";
				modelMap.put("oldPasswordv", oldPasswordv);
		}
		}
        modelMap.put("status", status);
        modelView.addAllObjects(modelMap);
        return modelView;
	}

	/**
	 * 通过email和密码获取用户信息
	 * @param email 
	 * @param password
	 * @return 用户对象
	*/
	public User getUserInfo(String email, String password) {
		String sql = "select * from user where email=? and password=?";
		try {
			Map<String, Object> map = jdbcTemplate.queryForMap(sql, email, password);
			User user = parseUser(map);
			return user;
		} catch (DataAccessException e) {
			e.printStackTrace();
			return null;
		}
	}


	/**
	 * 完成用户的注册
	 * @param name      用户名
	 * @param email     email
	 * @param password  密码
	 * @param type      用户类型
	 * @return 完成注册的用户对象
	*/
	public User registerUser(String name, String email, String password, String type) {
		String sql1 = "insert into user (id, name, email, password, type,checkcode) values (0, ?, ?, ?, ?, ?)";
		String sql2 = "select id, reg_time from user where email=?";
		try {
			jdbcTemplate.update(sql1, name, email, password, type,DataUtil.randomCheckCode());
			Map<String, Object> map = jdbcTemplate.queryForMap(sql2, email);
			int id = (Integer)map.get("id");
			Timestamp ts = (Timestamp)map.get("reg_time");
			String regTime = SDF.format(ts);

			User user = new User(id, email, name, password, type, regTime);
			return user;
		} catch (DataAccessException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 通过email判断用户是否唯一
	 * @param email
	 * @return true：用户不唯一，false：用户唯一
	 */
	public boolean isUserExist(String email) {
		String sql = "select count(*) FROM `user` WHERE email=? ";
		try {
			int cnt = jdbcTemplate.queryForInt(sql, email.trim());
			return cnt > 0;
		} catch (DataAccessException e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 把Map里的用户信息复制到User对象中
	 * @param map  
	 * @return User对象
	*/
	private User parseUser(Map<String, Object> map) {
		int id = (Integer)map.get("id");
		String name = (String)map.get("name");
		String email = (String)map.get("email");
		String password = (String)map.get("password");
		String type = String.valueOf((Integer)map.get("type"));
		Timestamp ts = (Timestamp)map.get("reg_time");
		String regTime = SDF.format(ts);
		return new User(id, email, name, password, type, regTime);
	}
	
	/**
	 * 判断用户Id是否存在
	 * @param uid 用户Id
	 * @return true：用户Id存在，false：不存在
	*/
	public boolean isUserIdExist(int uid) {
		String sql = "select id from user where id=?";
		try {
			List<Map<String, Object>> ret = jdbcTemplate.queryForList(sql, uid);
			return (ret != null && !ret.isEmpty());
		}
		catch (DataAccessException e) {
			e.printStackTrace();
		}
		return false;
	}
	
	/**
	 * 根据用户Id保存修改后的密码
	 * @param userId       用户Id
	 * @param oldPassword  旧密码
	 * @param newPassword  新密码
	 * @return true：保存完成，false：保存失败
	*/
	public boolean modifyPassword(long userId , String oldPassword, String newPassword) {
		String oldPasswordmd5 = MD5.getEncryptedPwd(oldPassword);
		String newPasswordmd5 = MD5.getEncryptedPwd(newPassword);
		try {
			String sql = "select password from user where id = ?";
			Map<String, Object> ret = jdbcTemplate.queryForMap(sql, userId);
			if (ret != null) {
				String password = (String)ret.get("password");
				if (!password.equals(oldPasswordmd5)) {
					return false;
				}	
				sql = "update user set password = ? where id = ?";
				jdbcTemplate.update(sql, newPasswordmd5, userId);
				return true;
			}
			
			return (ret != null && !ret.isEmpty());
		}
		catch (DataAccessException e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 更新email账号的动态核对码
	 * @param email
	 * @param checkcode 
	*/
	public void updataCheckCode(String email, String checkcode) {
		String updataSql = "update user set checkcode=? where email=? ";
		jdbcTemplate.update(updataSql,checkcode,email);
		
		
	}

	/**
	 * 检查动态码是否有效
	 * @param email
	 * @param checkcode 
	 * @return true：有效；false：无效
	*/
	public boolean checkCode(String email, String checkcode){
		String sql = "select count(*) from user where email=? and checkcode=?";
		if(jdbcTemplate.queryForInt(sql,email,checkcode)>0){
			return true;
		}
		return false;
		
	}

	/**
	 * 通过email账号修改密码和动态码
	 * @param password
	 * @param email
	 * @return true：成功；false：失败
	*/
	public boolean modifyPswByEmail(String password, String email) {
		String sql1 = "select count(*) from user where email = ?";
		String sql2 = "update user set password=? , checkcode=? where email = ?";
		if(jdbcTemplate.queryForInt(sql1,email.trim())>0){
			jdbcTemplate.update(sql2,password.trim(),DataUtil.randomCheckCode(),email.trim());
			return true;
		}else{
			return false;
		}
	}

}
